Fix rust 40955
authorJakub Matraszek <jakub.matraszek@gmail.com>
Tue, 4 Apr 2017 21:58:31 +0000 (23:58 +0200)
committerJakub Matraszek <jakub.matraszek@gmail.com>
Tue, 4 Apr 2017 21:58:31 +0000 (23:58 +0200)
src/cargo/util/toml.rs
tests/build.rs

index 197dfca8c0ce3f1232411d84d9b8067355d844c5..157295246c2e93ecc0426e8c05becdc5efa82b63 100644 (file)
@@ -1273,17 +1273,7 @@ fn normalize(package_root: &Path,
                        default: &mut FnMut(&TomlBinTarget) -> PathBuf| {
         for bin in bins.iter() {
             let path = bin.path.clone().unwrap_or_else(|| {
-                let default_bin_path = PathValue(default(bin));
-                if package_root.join(&default_bin_path.0).exists() {
-                    default_bin_path // inferred from bin's name
-                } else {
-                    let path = PathValue(Path::new("src").join("main.rs"));
-                    if package_root.join(&path.0).exists() {
-                        path
-                    } else {
-                        PathValue(Path::new("src").join("bin").join("main.rs"))
-                    }
-                }
+                PathValue(default(bin))
             });
             let mut target = Target::bin_target(&bin.name(), package_root.join(&path.0),
                                                 bin.required_features.clone());
@@ -1359,14 +1349,13 @@ fn normalize(package_root: &Path,
     if let Some(ref lib) = *lib {
         lib_target(&mut ret, lib);
         bin_targets(&mut ret, bins,
-                    &mut |bin| Path::new("src").join("bin")
-                                   .join(&format!("{}.rs", bin.name())));
+                    &mut |bin| inferred_bin_path(bin, package_root, true, bins.len()));
     } else if bins.len() > 0 {
         bin_targets(&mut ret, bins,
-                    &mut |bin| Path::new("src")
-                                    .join(&format!("{}.rs", bin.name())));
+                    &mut |bin| inferred_bin_path(bin, package_root, false, bins.len()));
     }
 
+
     if let Some(custom_build) = custom_build {
         custom_build_target(&mut ret, &custom_build);
     }
@@ -1394,6 +1383,53 @@ fn normalize(package_root: &Path,
     ret
 }
 
+fn inferred_bin_path(bin: &TomlBinTarget, package_root: &Path, lib: bool, bin_len: usize) -> PathBuf {
+    // we have a lib with multiple bins, so the bins are expected to be located inside src/bin
+    if lib && bin_len > 1 {
+        return Path::new("src").join("bin").join(&format!("{}.rs", bin.name())).to_path_buf()
+    }
+
+    // we have a lib with one bin, so it's either src/main.rs, src/bin/foo.rs or src/bin/main.rs
+    if lib && bin_len == 1 {
+        let path = Path::new("src").join(&format!("main.rs"));
+        if package_root.join(&path).exists() {
+            return path.to_path_buf()
+        }
+
+        let path = Path::new("src").join("bin").join(&format!("{}.rs", bin.name()));
+        if package_root.join(&path).exists() {
+            return path.to_path_buf()
+        }
+
+        return Path::new("src").join("bin").join(&format!("main.rs")).to_path_buf()
+    }
+
+    // here we have a single bin, so it may be located in src/main.rs, src/foo.rs,
+    // srb/bin/foo.rs or src/bin/main.rs
+    if bin_len == 1 {
+        let path = Path::new("src").join(&format!("main.rs"));
+        if package_root.join(&path).exists() {
+            return path.to_path_buf()
+        }
+
+        let path = Path::new("src").join(&format!("{}.rs", bin.name()));
+        if package_root.join(&path).exists() {
+            return path.to_path_buf()
+        }
+
+        let path = Path::new("src").join("bin").join(&format!("{}.rs", bin.name()));
+        if package_root.join(&path).exists() {
+            return path.to_path_buf()
+        }
+
+        return Path::new("src").join("bin").join(&format!("main.rs")).to_path_buf()
+
+    }
+
+    // here we have multiple bins, so they are expected to be located inside src/bin
+    Path::new("src").join("bin").join(&format!("{}.rs", bin.name())).to_path_buf()
+}
+
 fn build_profiles(profiles: &Option<TomlProfiles>) -> Profiles {
     let profiles = profiles.as_ref();
     let mut profiles = Profiles {
index dfa6241beabbc89288f280847eb9c4ef4b5af480..1eea86b5cb2c26c7e94963e6d7570a7d518c6f4b 100644 (file)
@@ -2870,3 +2870,28 @@ fn run_proper_binary_main_rs() {
     assert_that(p.cargo_process("run").arg("--bin").arg("foo"),
                 execs().with_status(0));
 }
+
+#[test]
+fn run_proper_binary_main_rs_as_foo() {
+    let p = project("foo")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "foo"
+            authors = []
+            version = "0.0.0"
+            [[bin]]
+            name = "foo"
+        "#)
+        .file("src/foo.rs", r#"
+            fn main() {
+                panic!("This should never be run.");
+            }
+        "#)
+        .file("src/main.rs", r#"
+            fn main() {
+            }
+        "#);
+
+    assert_that(p.cargo_process("run").arg("--bin").arg("foo"),
+                execs().with_status(0));
+}